package com.noties.markwon.wrapper.graphics.drawable;

import com.noties.markwon.annotation.IntRange;
import com.noties.markwon.annotation.NonNull;
import com.noties.markwon.annotation.Nullable;

import java.lang.ref.WeakReference;
import ohos.agp.render.Canvas;
import ohos.agp.render.ColorFilter;
import ohos.agp.utils.Rect;

/**
 * @author: yangrui
 * @function: open open harmony lack class
 * @date: 2021/3/23
 */
public abstract class Drawable {
    private static final Rect ZERO_BOUNDS_RECT = new Rect();

    private WeakReference<Callback> mCallback = null;
    private Rect mBounds = ZERO_BOUNDS_RECT;

    public abstract void draw(@NonNull Canvas canvas);

    public abstract void setAlpha(@IntRange(from = 0, to = 255) int alpha);

    public abstract void setColorFilter(@Nullable ColorFilter colorFilter);

    @Deprecated
    public abstract int getOpacity();

    public int getIntrinsicWidth() {
        return -1;
    }

    public int getIntrinsicHeight() {
        return -1;
    }


    public interface Callback {

        void invalidateDrawable(@NonNull Drawable who);

        void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when);

        void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what);
    }

    public final void setCallback(@Nullable Callback cb) {
        mCallback = cb != null ? new WeakReference<>(cb) : null;
    }

    @Nullable
    public Callback getCallback() {
        return mCallback != null ? mCallback.get() : null;
    }

    /**
     * Specify a bounding rectangle for the Drawable. This is where the drawable
     * will draw when its draw() method is called.
     */
    public void setBounds(@NonNull Rect bounds) {
        // setBounds(bounds.left, bounds.top, bounds.right, bounds.bottom);
    }

    public void setBounds(int left, int top, int right, int bottom) {
//        Rect oldBounds = mBounds;
//
//        if (oldBounds == ZERO_BOUNDS_RECT) {
//            oldBounds = mBounds = new Rect();
//        }
//
//        if (oldBounds.left != left || oldBounds.top != top ||
//                oldBounds.right != right || oldBounds.bottom != bottom) {
//            if (!oldBounds.isEmpty()) {
//                // first invalidate the previous bounds
//                invalidateSelf();
//            }
//            mBounds.set(left, top, right, bottom);
//            onBoundsChange(mBounds);
//        }
    }

    protected void invalidateSelf() {
        final Callback callback = getCallback();
        if (callback != null) {
            callback.invalidateDrawable(this);
        }
    }

    @NonNull
    public final Rect getBounds() {
        if (mBounds == ZERO_BOUNDS_RECT) {
            mBounds = new Rect();
        }

        return mBounds;
    }

    protected void onBoundsChange(Rect bounds) {

    }

    public void setState(int[] state){};

    public boolean isStateful() {
        return true;
    }

    protected boolean onStateChange(int[] state) {
        return true;
    }
}
